// 引入路由需要的相关模块 vue 和 vue-router
import Vue from "vue";
import VueRouter from "vue-router";
// 引入相关的组件
/* import Home from "../components/Home";
import About from "../components/About";
import User from "../components/User"; */

// 使用懒加载来引入相关组件
const Home = () => import("../components/Home");
const HomeNews = () => import("../components/HomeNews")
const HomeMessage = () => import("../components/HomeMessage")

const About = () => import("../components/About");
const User = () => import("../components/User");
const Profile = () => import("../components/Profile")

// 捕获重复点击路由的报错
const originalPush = VueRouter.prototype.push

VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}

// 构建路由需要三步
// 1. 通过Vue.use() 使用路由
Vue.use(VueRouter);

// 2. 创建一个路由实例
// 抽离出来的路由与组件的映射关系
const routes = [{
    path: "/",
    redirect: "/home"
  },
  // 一条映射信息就是一个对象, 对象中的path和component构成一个映射
  {
    path: "/home", // 用的是path, 而不是url, 因为url是一个完整的地址, 我们只需要修改地址中的一部分, 所以用path
    component: Home, // 挂载组件
    meta: {
      title: "首页"
    },
    children: [
      // 要实现保留组件状态就不能自动跳转
      /* {
        path : "",
        redirect : "news"
      }, */
      {
        path: "news", // 注意嵌套在路由里面的路由路径前面不能加 /
        component: HomeNews,
      },
      {
        path: "message",
        component: HomeMessage,
      }
    ]
  },
  {
    path: "/about",
    component: About,
    meta: {
      title: "关于"
    }
  },
  {
    path: "/user/:userId", // 这里的 /user/ 为确定的路径, :userId 为不确定的路径, 不过要记住冒号后面的名字, 因为可以在组件中获取这个名字 
    component: User,
    meta: {
      title: "用户"
    }
  },
  {
    path: "/profile",
    component: Profile,
    meta: {
      title: "档案"
    }
  }
]

const router = new VueRouter({
  // 编写路由与组件的映射关系, 可以将其抽离出去
  routes,
  // 将修改url中的hash值来改变展示的组件, 转换为通过history方法来改变
  mode: "history",
  // 可以通过 linkActiveClass 这个选项来修改 默认的类名称
  linkActiveClass: "active"
})

// 通过 路由实例中的 beforeEach 方法来监听路由即将改变前事件
// 这个方法需要传入一个参数, 这个参数是一个函数
// 这个函数包含三个参数, 第一个参数为to, 第二个参数为from, 第三个参数为next(其本质是一个函数)
// to指要跳转到的路由, from指从哪个路由跳转, next指进行下一步操作, [注]必须调用next函数,进行下一步,否则路由不会跳转了
// to和from都是是一个路由对象里面包含整个路由的所有信息, 包括其父路由
router.beforeEach((to, from, next) => {
  // 如果存在路由嵌套的话, 直接用meta是拿不到元数据的
  // 要通过to对象中的metched数组中下标为0的数据中的meta对象来获取预先在路由中设置的元数据
  // console.log(to);  
  document.title = to.matched[0].meta.title;
  next(); // 调用next函数进行下一步
})

// 3. 将路由导出, 并在main.js中的Vue实例中挂载创建的路由实例
export default router;
